package com.ytf.dogbox.util;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class BitmapUtil {


    /**
     * 将图片倒转一个角度
     * @param bitmap  原先的图片
     * @param degrees 倒转的角度
     * @return
     */
    public static Bitmap turnBitmap(Bitmap bitmap,int degrees){

        Matrix matrix=new Matrix();
        matrix.postRotate(degrees);
        Bitmap resizedBitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
        if (resizedBitmap!=bitmap && bitmap!=null && !bitmap.isRecycled()){
            bitmap.recycle();
            bitmap=null;
        }
        return resizedBitmap;
    }

    /**
     * 给图片打上水印
     * @param bitmap 原先的图片
     * @param waterMark 水印信息
     * @param location 水印位置
     * @param color 水印颜色
     * @param alpha 水印透明度
     * @param size 水印文字大小
     * @param underline 是否添加下划线
     * @return
     */
    public static Bitmap markBitmap(Bitmap bitmap, String waterMark, Point location, int color, int alpha, int size, boolean underline){
        Canvas canvas=new Canvas(bitmap);
        canvas.drawBitmap(bitmap,0,0,null);

        Paint paint=new Paint();
        paint.setColor(color);
        paint.setAlpha(alpha);
        paint.setAntiAlias(true);
        paint.setUnderlineText(underline);
        paint.setTextSize(size);
        canvas.drawText(waterMark,location.x,location.y,paint);

        return bitmap;

    }

    /**
     * 获取到YUV420sp格式图片
     * @param bitmap
     * @return
     */
    public static byte[] getYuv(Bitmap bitmap){
//        Bitmap bMap= BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() +"/intefly/picture/te.jpg");
        int width=bitmap.getWidth();
        int height=bitmap.getHeight();
        int[] argbArray=new int[width * height];
        bitmap.getPixels(argbArray,0,width,0,0,width,height);
        byte[] yuvArray=new byte[width * height * 3 / 2];
        encodeYUV420SP(yuvArray,argbArray,width,height);
        //bMap.recycle();
        return yuvArray;
    }

    public static void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width, int height) {
        final int frameSize = width * height;

        int yIndex = 0;
        int uvIndex = frameSize;

        int a, R, G, B, Y, U, V;
        int index = 0;
        for (int j = 0; j < height-1; j++) {
            for (int i = 0; i < width-1; i++) {

                a = (argb[index] & 0xff000000) >> 24; // a is not used obviously
                R = (argb[index] & 0xff0000) >> 16;
                G = (argb[index] & 0xff00) >> 8;
                B = (argb[index] & 0xff) >> 0;

                // well known RGB to YUV algorithm
                Y = ( (  66 * R + 129 * G +  25 * B + 128) >> 8) +  16;
                U = ( ( -38 * R -  74 * G + 112 * B + 128) >> 8) + 128;
                V = ( ( 112 * R -  94 * G -  18 * B + 128) >> 8) + 128;

                // NV21 has a plane of Y and interleaved planes of VU each sampled by a factor of 2
                //    meaning for every 4 Y pixels there are 1 V and 1 U.  Note the sampling is every other
                //    pixel AND every other scanline.
                yuv420sp[yIndex++] = (byte) ((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));
                if (j % 2 == 0 && index % 2 == 0) {
                    yuv420sp[uvIndex++] = (byte)((V<0) ? 0 : ((V > 255) ? 255 : V));
                    yuv420sp[uvIndex++] = (byte)((U<0) ? 0 : ((U > 255) ? 255 : U));
                }

                index ++;
            }
        }
    }

    /**
     * 降低bitmap转byte[]数组所需的空间试下
     * @param bitmap
     * @param quality
     * @return
     */
    public static byte[] bitmabToBytes(Bitmap bitmap,int quality){
        //将图片转化为位图
        ///Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
        int size = bitmap.getWidth() * bitmap.getHeight() * 4;
        ByteArrayOutputStream baos=null;
        try {
            //创建一个字节数组输出流,流的大小为size
//            baos= new ByteArrayOutputStream(size);  //todo 是否因为这个导致oom？
            baos=new ByteArrayOutputStream();
            //设置位图的压缩格式，质量为100%，并放入字节数组输出流中
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
            //将字节数组输出流转化为字节数组byte[]
            byte[] imagedata = baos.toByteArray();
            return imagedata;
        }catch (Exception e){
            Log.e("tiwolf", "bitmabToBytes: 字节数组大小--"+size+";异常--"+e.getMessage() );
        }finally {
            try {
                bitmap.recycle();
                bitmap=null;
                if (baos!=null){
                    baos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return new byte[0];
    }

    /** * 将拍下来的照片存放在SD卡中 * @param data * @throws IOException */
    /**
     *
     * @param data  图片数据
     * @param fileName 文件夹名称
     * @param mp4Name 相对应的MP4名称
     * @param flag A表示是人，B表示是车
     * @param index 排序
     * @return
     * @throws IOException
     */
    public static File saveToSDCard(String path,byte[] data,String fileName,String mp4Name,String flag,int index) throws IOException {

        // + "/rebot/cache/");
        String filename=mp4Name+"_"+flag+"_"+index+".jpg";

        File fileFolder = new File(path + "/solar/"+fileName+"/");

        if (!fileFolder.exists()) {
            fileFolder.mkdir();
        }
        File fileCamera=new File(fileFolder+"/picture/");
        if (!fileCamera.exists()){
            fileCamera.mkdir();
        }
        File jpgFile = new File(fileCamera, filename);
//        FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流
//        outputStream.write(data); // 写入sd卡中
//        outputStream.close(); // 关闭输出流
        long start=System.currentTimeMillis();
        RandomAccessFile writer=new RandomAccessFile(jpgFile,"rw");
        FileChannel channel=writer.getChannel();
        ByteBuffer buffer=ByteBuffer.wrap(data);
        channel.write(buffer);
        buffer.clear();
        channel.close();
        Log.e("tiwolf", "saveToSDCard:保存一张识别到的图片所需时间为 "+(System.currentTimeMillis()-start));
        return jpgFile;
    }

    /** * 将拍下来的照片存放在SD卡中 * @param data * @throws IOException */
    /**
     * todo 2021.10.18 try-catch 直接在这里解决，不外抛异常
     * @param data  图片数据
     * @param fileName 文件夹名称
     * @param mp4Name 相对应的MP4名称
     * @param flag A表示是人，B表示是车
     * @param index 排序
     * @return
     * @throws IOException
     */
    public static File saveToSDCard1(String path,byte[] data,String fileName,String mp4Name,String flag,int index)  {

        // + "/rebot/cache/");
        String filename=mp4Name+"_"+flag+"_"+index+".jpg";

        File fileFolder = new File(path + "/solar/"+fileName+"/picture");

        if (!fileFolder.exists()) {
            fileFolder.mkdirs();
        }
//        File fileCamera=new File(fileFolder+"/picture/");
//        if (!fileCamera.exists()){
//            fileCamera.mkdir();
//        }
        File jpgFile = new File(fileFolder, filename);
//        FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流
//        outputStream.write(data); // 写入sd卡中
//        outputStream.close(); // 关闭输出流
        long start=System.currentTimeMillis();

        RandomAccessFile writer=null;
        FileChannel channel=null;
        ByteBuffer buffer=null;
        try {
            writer=new RandomAccessFile(jpgFile,"rw");
            channel=writer.getChannel();
            buffer=ByteBuffer.wrap(data);
            channel.write(buffer);
//            buffer.clear();
//            channel.close();
//            channel=null;
        } catch (IOException e) {
            e.printStackTrace();
            jpgFile=null;
        }finally {
            if (buffer!=null){
                buffer.clear();
                buffer=null;
            }
            if (channel!=null){
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                channel=null;
            }
            if (writer!=null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                writer=null;
            }
        }

        Log.e("tiwolf", "saveToSDCard:保存一张识别到的图片所需时间为 "+(System.currentTimeMillis()-start));
        return jpgFile;
    }


    /** * 将拍下来的照片存放在SD卡中 * @param data * @throws IOException */
    /**
     *
     * @param data  图片数据   做成缩略图
     * @param fileName 文件夹名称
     * @param mp4Name 相对应的MP4名称
     * @return
     * @throws IOException
     */
    public static File saveToSDCard(String path,byte[] data,String fileName,String mp4Name) throws IOException {

        String filename=mp4Name+".jpg";

        File fileFolder = new File(path + "/solar/"+fileName+"/");

        if (!fileFolder.exists()) {
            fileFolder.mkdir();
        }
        File fileCamera=new File(fileFolder+"/picture/");
        if (!fileCamera.exists()){
            fileCamera.mkdir();
        }

        long start=System.currentTimeMillis();
        File jpgFile = new File(fileCamera, filename);
//        FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流
//        outputStream.write(data); // 写入sd卡中
//        outputStream.close(); // 关闭输出流


        RandomAccessFile writer=new RandomAccessFile(jpgFile,"rw");
        FileChannel channel=writer.getChannel();
        ByteBuffer buffer=ByteBuffer.wrap(data);
        channel.write(buffer);
        buffer.clear();
        channel.close();

        Log.e("tiwolf", "saveToSDCard:保存一张mp4封面图片所需时间为 "+(System.currentTimeMillis()-start));

        return jpgFile;
    }

    /** * 将拍下来的照片存放在SD卡中 * @param data * @throws IOException */
    /**
     * todo 2021.10.18 try-catch 直接在这里解决，不外抛异常
     * @param data  图片数据   做成缩略图
     * @param fileName 文件夹名称
     * @param mp4Name 相对应的MP4名称
     * @return
     * @throws IOException
     */
    public static File saveToSDCard2(String path,byte[] data,String fileName,String mp4Name) {

        String filename=mp4Name+".jpg";

        File fileFolder = new File(path + "/solar/"+fileName+"/");

        if (!fileFolder.exists()) {
            fileFolder.mkdir();
        }
        File fileCamera=new File(fileFolder+"/picture/");
        if (!fileCamera.exists()){
            fileCamera.mkdir();
        }

        long start=System.currentTimeMillis();
        File jpgFile = new File(fileCamera, filename);
//        FileOutputStream outputStream = new FileOutputStream(jpgFile); // 文件输出流
//        outputStream.write(data); // 写入sd卡中
//        outputStream.close(); // 关闭输出流

        RandomAccessFile writer=null;
        FileChannel channel=null;
        ByteBuffer buffer=null;
        try{
            writer=new RandomAccessFile(jpgFile,"rw");
            channel=writer.getChannel();
            buffer=ByteBuffer.wrap(data);
            channel.write(buffer);

        } catch (IOException e) {
            e.printStackTrace();
            jpgFile=null;
        }finally {
            if (buffer!=null){
                buffer.clear();
                buffer=null;
            }
            if (channel!=null){
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                channel=null;
            }
            if (writer!=null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                writer=null;
            }
        }


        Log.e("tiwolf", "saveToSDCard:保存一张mp4封面图片所需时间为 "+(System.currentTimeMillis()-start));

        return jpgFile;
    }



    /** * 将拍下来的照片存放在SD卡中 * @param data * @throws IOException */
    /**
     * todo 2021.10.18 try-catch 直接在这里解决，不外抛异常
     * @param data  图片数据   做成缩略图
     * @param fileName 文件夹名称
     * @param mp4Name 相对应的MP4名称
     * @return
     * @throws IOException
     */
    public static File saveToSDCard1(String path,byte[] data,String fileName,String mp4Name) {

        String filename=mp4Name+".jpg";

        File fileFolder = new File(path + "/solar/"+fileName+"/picture/");

        if (!fileFolder.exists()) {
            fileFolder.mkdirs();
        }
//        File fileCamera=new File(fileFolder+"/picture/");
//        if (!fileCamera.exists()){
//            fileCamera.mkdir();
//        }

        long start=System.currentTimeMillis();
        File jpgFile = new File(fileFolder, filename);
        FileOutputStream fos = null;
        try{
            fos=new FileOutputStream(jpgFile);
            fos.write(data,0,data.length);
            fos.flush();
            //等待100毫秒，直到该文件的占用者释放了该文件或者关闭了该文件
            Thread.sleep(100);
        }  catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos!=null){
                    fos.close();
                    fos=null;
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        Log.e("tiwolf", "saveToSDCard:保存一张识别到的图片所需时间为 "+(System.currentTimeMillis()-start));
        return jpgFile;
    }


    /**
     * 把Bitmap转Byte
     * @Author HEH
     * @EditTime 2010-07-19 上午11:45:56
     */
    public static byte[] Bitmap2Bytes(Bitmap bm){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }


    /**
     *  将字节数组转换为ImageView可调用的Bitmap对象
     * @param bytes
     * @param opts
     * @return Bitmap
     */
    public static Bitmap getPicFromBytes(byte[] bytes,
                                         BitmapFactory.Options opts) {
        if (bytes != null)
            if (opts != null)
                return BitmapFactory.decodeByteArray(bytes, 0, bytes.length,
                        opts);
            else
                return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        return null;
    }

    public static Bitmap big(Bitmap bitmap,float sx,float sy) {
        Matrix matrix = new Matrix();
//        matrix.postScale(1.5f,1.5f); //长和宽放大缩小的比例
        matrix.postScale(sx,sy); //长和宽放大缩小的比例
        Bitmap resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
        return resizeBmp;
    }


    public static Bitmap small(Bitmap bitmap,float sx,float sy) {
        Matrix matrix = new Matrix();
//        matrix.postScale(0.8f,0.8f); //长和宽放大缩小的比例
        matrix.postScale(sx,sy); //长和宽放大缩小的比例
        Bitmap resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
        return resizeBmp;
    }

}
